import re

from django import http
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage
from django.db import DatabaseError
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.areas.models import Address
from apps.orders.models import OrderInfo
from apps.shoppingcart.utils import merge_cart_cookie_to_redis
from apps.users.models import User
from utils import contents
from utils.response_code import RETCODE


class RegisterView(View):
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):

        username = request.POST.get('username')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        mobile = request.POST.get('mobile')
        allow = request.POST.get('allow')
        sms_code = request.POST.get('sms_code')

        if not all([username, password, password2, mobile, allow]):
            return http.HttpResponseBadRequest('缺少必传参数')

        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return http.HttpResponseBadRequest('请输入５－２０个字符的用户名')

        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return http.HttpResponseBadRequest('请输入8-20位的密码')

        if password != password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')

        if not re.match(r'1[3-9]\d{9}$', mobile):
            return http.HttpResponseBadRequest('请输入正确的手机号码')

        if allow != 'on':
            return http.HttpResponseBadRequest('请勾选用户协议')

        redis_conn = get_redis_connection('code')
        sms_code_saved = redis_conn.get('sms_%s' % mobile)
        if sms_code_saved is None:
            return render(request, 'register.html', {'sms_code_errmsg': '无效的验证码'})

        if sms_code_saved.decode() != sms_code:
            return render(request, 'register.html', {'sms_code_errmsg': '短信验证码错误'})

        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile)
        except DatabaseError:
            return render(request, 'register.html', {'register_errmsg': '注册失败'})

        login(request, user)

        response = redirect(reverse('index:index'))
        response.set_cookie('username', user.username, 3600 * 24 * 15)
        return response


class UsernameCountView(View):
    def get(self, request, username):
        count = User.objects.filter(username=username).count()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': "OK", 'count': count})


class MobileCountView(View):
    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile).count()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'count': count})


class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):

        username = request.POST.get('username')
        password = request.POST.get('password')
        remembered = request.POST.get('remembered')

        if not all([username, password]):
            return http.HttpResponseBadRequest('缺少必须参数')

        if not re.match(r'^[a-zA-Z0-9_]{5,20}', username):
            return render(request, 'login.html', {'account_errmsg': '请输入正确的用户名手机号'})

        if not re.match(r'^[a-zA-Z0-9]{8,20}', password):
            return render(request, 'login.html', {'account_errmsg': '密码8-20位'})

        user = authenticate(username=username, password=password)
        if user is None:
            return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'})

        login(request, user)

        if remembered != 'on':
            request.session.set_expiry(0)
        else:
            request.session.set_expiry(None)

        next = request.GET.get('next')

        if next:
            response = redirect(next)
        else:

            response = redirect((reverse('index:index')))

        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)

        return response


class LogoutView(View):
    def get(self, request):
        logout(request)

        response = redirect(reverse('index:index'))

        response.delete_cookie('username')

        return response


class UserCenterView(LoginRequiredMixin, View):
    def get(self, request):
        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }

        return render(request, 'base_user_center.html', context=context)


class AddressView(View):
    def get(self, request):
        addresses = Address.objects.filter(user=request.user, is_deleted=False)

        address_dict_list = []

        for address in addresses:
            address_dict = {
                'id': address.id,
                'city_id': address.city_id,
                'city': address.city.name,
                'district_id': address.district_id,
                'district': address.district.name,
                'email': address.email,
                'mobile': address.mobile,
                'place': address.place,
                'province_id': address.province_id,
                'province': address.province.name,
                'receiver': address.receiver,
                'tel': address.tel,
                'title': address.title
            }
            address_dict_list.append(address_dict)

        context = {
            'default_address_id': request.user.default_address_id,
            'addresses': address_dict_list,
        }

        return render(request, 'base_user_center_site.html', context=context)


class ChangePasswordView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'base_user_center_pass.html')

    def post(self, request):

        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        new_password2 = request.POST.get('new_password2')

        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseBadRequest('缺少必传参数')

        if not re.match(r'^[a-zA-Z0-9]{8,20}$', new_password):
            return http.HttpResponseBadRequest('密码最少8位，最长20位')

        if new_password != new_password2:
            return http.HttpResponseBadRequest('两次密码不一致')

        if not request.user.check_password(old_password):
            return render(request, 'user_center_pass.html', {'origin_password_errmsg': '原始密码错误'})

        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '修改密码失败'})

        logout(request)

        response = redirect(reverse('users:login'))

        response.delete_cookie('username')

        return response


class UserOrderInfoView(LoginRequiredMixin, View):
    def get(self, request, page_num):
        user = request.user
        orders = user.orderinfo_set.all().order_by('-create_time')
        for order in orders:
            order.status_name = OrderInfo.ORDER_STATUS_CHOICES[order.status - 1][1]
            order.pay_method_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method - 1][1]
            order.sku_list = []
            order_goods = order.skus.all()
            for order_good in order_goods:
                sku = order_good.sku
                sku.count = order_good.count
                sku.amount = sku.count * sku.price
                order.sku_list.append(sku)

        page_num = int(page_num)
        try:
            paginator = Paginator(orders, contents.ORDERS_LIST_LIMIT)
            page_orders = paginator.page(page_num)
            total_page = paginator.num_pages
        except EmptyPage:
            return http.HttpResponseBadRequest('订单不存在')

        context = {
            'page_orders': page_orders,
            'total_page': total_page,
            'page_num': page_num
        }

        return render(request, 'user_center_order.html', context)
